<template>
  <div>
    <a-transfer
      class="tree-transfer"
      :title="['', '']"
      :data-source="dataSource"
      :target-keys="targetKeys"
      :render="item => item.rightName"
      :show-select-all="false"
      :filterOption="() => true"
      @change="onChange"
    >
      <template #children="{ direction, selectedKeys, onItemSelect }">
        <a-tree
          v-if="direction === 'left'"
          blockNode
          checkable
          checkStrictly
          :checkedKeys="[...selectedKeys, ...targetKeys]"
          :treeData="treeData"
          @check="
            (_, props) => {
              onChecked(_, props, [...selectedKeys, ...targetKeys], onItemSelect);
            }
          "
          @select="
            (_, props) => {
              onChecked(_, props, [...selectedKeys, ...targetKeys], onItemSelect);
            }
          "
        />
      </template>
    </a-transfer>
  </div>
</template>
<script>
import { computed, defineComponent, ref, toRaw, toRefs, watch } from 'vue';
const transferDataSource = [];

function flatten(list = []) {
  list.forEach(item => {
    transferDataSource.push(item);
    flatten(item.children);
  });
}

// flatten(JSON.parse(JSON.stringify(tData)));

function isChecked(selectedKeys, eventKey) {
  return selectedKeys.indexOf(eventKey) !== -1;
}

function handleTreeData(data, targetKeys = []) {
  data.forEach(item => {
    item['disabled'] = targetKeys.includes(item.key);

    if (item.children) {
      handleTreeData(item.children, targetKeys);
    }
  });
  return data;
}

export default defineComponent({
  props: {
    tData: {
      type: Array,
      default: () => [],
    },
    value: {
      type: Array,
      default: () => [],
    },
  },
  setup(props, { emit }) {
    const { tData, value } = toRefs(props);
    const data = toRaw(tData.value);
    flatten(JSON.parse(JSON.stringify(data)));

    const targetKeys = ref(toRaw(value.value));
    watch(value, key => {
      targetKeys.value = key;
    });
    const dataSource = ref(transferDataSource);
    const treeData = computed(() => {
      return handleTreeData(data, targetKeys.value);
    });

    const onChange = keys => {
      emit('update:value', keys);
      emit('change', keys);
      targetKeys.value = keys;
    };

    const onChecked = (_, e, checkedKeys, onItemSelect) => {
      const { eventKey } = e.node;
      onItemSelect(eventKey, !isChecked(checkedKeys, eventKey));
      emit('onChecked', _, e, checkedKeys, onItemSelect);
    };

    return {
      targetKeys,
      dataSource,
      treeData,
      onChange,
      onChecked,
    };
  },
  emits: {
    'update:value': null,
    change: null,
    onChecked: null,
  },
});
</script>
<style lang="less">
.tree-transfer {
  width: 640px;
  .ant-transfer-list {
    width: 180px;
  }
}
</style>
